# -*- coding: utf-8 -*-
"""
coder:yanzg
"""
import logging
import traceback

from blueapps.core.exceptions.base import MethodError
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.db import IntegrityError

from blueapps import metrics
from blueapps.account import get_user_model
from blueapps.account.conf import ConfFixture
from blueapps.account.utils.http import send
from blueapps.utils.sops_jwt_handler import SopsJwtHandler
from blueapps.utils.tools import resolve_login_url


logger = logging.getLogger("component")

ROLE_TYPE_ADMIN = "1"

TOKEN_TYPE = "sops_jwt"


class SopsJwtBackend(ModelBackend):
    def authenticate(self, request=None):
        logger.debug("Enter in Sops jwt Backend 认证")

        if not request.is_ajax:
            logger.debug("only for x-requested-with:XMLHttpRequest aka http ajax, skip SopsJwtBackend")
            return None

        try:
            verify_data = self.verify_sops_jwt_request(request)
        except Exception as err:  # pylint: disable=broad-except
            metrics.BLUEAPPS_USER_TOKEN_VERIFY_FAILED_TOTAL.labels(
                hostname=metrics.HOSTNAME, token_type=TOKEN_TYPE, err="unknow_execption_raise"
            ).inc()
            logger.exception("[SOPS_JWT]校验异常: %s" % err)
            return None

        if not verify_data["result"] or not verify_data["data"]:
            logger.error("SOPS_JWT 验证失败： %s" % verify_data)
            return None

        user_info = verify_data["data"]["user"]
        user_model = get_user_model()
        try:
            user = user_model.objects.get(username=user_info["bk_username"])

        except user_model.DoesNotExist:
            logger.exception(traceback.format_exc())
            logger.exception("username DoesNotExist")
            return None

        return user

    @staticmethod
    def verify_sops_jwt_request(request):
        """
        验证 SOPS_JWT 请求
        @param {string} HTTP_AUTHORIZATION JWT请求头
        @return {dict}
            {
                'result': True,
                'message': '',
                'data': {
                    'user': {
                        'bk_username': '调用方用户'
                    },
                    'app': {
                        'bk_app_code': '调用方app'
                    }
                }
            }
        """
        ret = {"result": False, "message": "", "data": {}}

        with metrics.observe(
            metrics.BLUEAPPS_USER_TOKEN_VERIFY_DURATION, hostname=metrics.HOSTNAME, token_type=TOKEN_TYPE
        ):
            # 开始解密并验证jwt
            jwt = SopsJwtHandler(request).get_jwt_info()

        if not jwt.is_valid:
            metrics.BLUEAPPS_USER_TOKEN_VERIFY_FAILED_TOTAL.labels(
                hostname=metrics.HOSTNAME, token_type=TOKEN_TYPE, err="invalid_jwt"
            ).inc()
            ret["message"] = _("jwt_invalid: %s") % jwt.error_message
            return ret

        # verify: app
        # yanzg 写死,只为与原报文一致 , 自定认证无需检查app合法性
        app = dict()
        app["bk_app_code"] = "bk_sops"

        # verify: user
        user = dict()
        username = jwt.get_username()


        if not username:
            metrics.BLUEAPPS_USER_TOKEN_VERIFY_FAILED_TOTAL.labels(
                hostname=metrics.HOSTNAME, token_type=TOKEN_TYPE, err="empty_username"
            ).inc()
            ret["message"] = _("无法获取用户名信息")
            return ret
        user["bk_username"] = username

        ret["result"] = True
        ret["data"] = {"user": user, "app": app}
        return ret

